<?php
/**
 * User: linzhv@qq.com
 * Date: 15/04/2018
 * Time: 08:53
 */
declare(strict_types=1);

namespace sharin {

    use sharin\core\Response;

    class TracePage
    {
        public function __toString()
        {

            if (SR_IS_CLI) return false;
            $status = Kernel::status();
//吞吐率  1秒/单次执行时间
            if (count($status) > 1) {
                $last = end($status);
                $first = reset($status);            //注意先end后reset
                $stat = [
                    1000 * round($last[0] - $first[0], 6),
                    number_format(($last[1] - $first[1]), 6)
                ];
            } else {
                $stat = [0, 0];
            }
            $requestPerSecond = empty($stat[0]) ? 'Unknown' : 1000 * number_format(1 / $stat[0], 8) . ' req/s';

//包含的文件数组
            $files = get_included_files();
            $info = [];
            $len = strlen(SR_PATH_ROOT);
            foreach ($files as $currentKey => $file) {
                $size = number_format(filesize($file) / 1024, 2);
                $file = substr($file, $len);
                $info[] = "{$file} Size:{$size} KB";
            }

//运行时间与内存开销
            $prevKey = null;
            $runtimeStatusString = ['Total' => "{$stat[0]}ms",];
            foreach ($status as $currentKey => $val) {
                if (null === $prevKey) {
                    $prevKey = $currentKey;
                    continue;
                }
                $currentMemory = number_format((floatval($status[$currentKey][1]) / 1024), 2);
                $previousMemory = number_format((floatval($status[$prevKey][1]) / 1024), 2);
                $runtimeStatusString["[$prevKey --> $currentKey] "] =
                    number_format(1000 * floatval($status[$currentKey][0] - $status[$prevKey][0]), 6) . 'ms&nbsp;&nbsp;' .
                    ($currentMemory - $previousMemory) . " KB ({$currentMemory} KB)";
                $prevKey = $currentKey;
            }


            $vars = [
                'General' => [
                    'request' => date('Y-m-d H:i:s', time()) . ' ' . $_SERVER['SERVER_PROTOCOL'] . ' ' . $_SERVER['REQUEST_METHOD'],
                    'time' => "{$stat[0]}ms",
                    'qps' => $requestPerSecond,//吞吐率
                    'session id' => session_id(),
                    'obcache-size' => number_format((ob_get_length() / 1024), 2) . ' KB',//不包括trace
                ],
                'Files' => array_merge(['Total' => count($info)], $info),
                'Status' => $runtimeStatusString,
                'GET' => $_GET,
                'POST' => $_POST,
                'REQUEST' => $_REQUEST,
                'SERVER' => $_SERVER,
                'ENV' => $_ENV,
                'COOKIE' => empty($_COOKIE) ? [] : $_COOKIE,
                'SESSION' => isset($_SESSION) ? $_SESSION : ['SESSION state disabled'],//session_start()之后$_SESSION数组才会被创建
                'IP' => [
                    '$_SERVER["HTTP_X_FORWARDED_FOR"]' => isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : 'NULL',
                    '$_SERVER["HTTP_CLIENT_IP"]' => isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : 'NULL',
                    '$_SERVER["REMOTE_ADDR"]' => $_SERVER['REMOTE_ADDR'],
                    'getenv("HTTP_X_FORWARDED_FOR")' => getenv('HTTP_X_FORWARDED_FOR'),
                    'getenv("HTTP_CLIENT_IP")' => getenv('HTTP_CLIENT_IP'),
                    'getenv("REMOTE_ADDR")' => getenv('REMOTE_ADDR'),
                ],
            ];

            $nav = $win = '';
            foreach ($vars as $currentKey => $value) {
                $nav .= "<span style=\"color:#000;padding-right:12px;height:30px;line-height: 30px;display:inline-block;margin-right:3px;cursor: pointer;font-weight:700\">$currentKey</span>";
                $win .= '<div style="display:none;"><ol style="padding: 0; margin:0">';
                if (is_array($value)) {
                    foreach ($value as $k => $val) {
                        if (!is_string($val)) $val = var_export($val, true);
                        $win .= '<li style="border-bottom:1px solid #EEE;font-size:14px;padding:0 12px"><span style="color: blue">' .
                            (is_numeric($k) ? '' : $k . ':</span>') .
                            "<span  style='color:black'>{$val}</span></li>";
                    }
                } else {
                    $win .= htmlspecialchars($value, ENT_COMPAT, 'utf-8');
                }
                $win .= '</ol></div>';
            }
            return <<<endline
    <div style="border-left:thin double #ccc;position: fixed;bottom:0;right:0;font-size:14px;width:840px;z-index: 999999;color: #000;text-align:left;font-family:'Times New Roman';cursor:default;">
        <div id="ptt" style="display: none;background:white;margin:0;height: 480px;">
            <!-- navigation bar -->
            <div id="pttt" style="height:32px;padding: 6px 12px 0;border-bottom:1px solid #ececec;border-top:1px solid #ececec;font-size:16px">
                {$nav}
            </div>
            <!-- detail window -->
            <div id="pttc" style="overflow:auto;height:478px;padding: 0; line-height: 24px">
                {$win}
            </div>
        </div>
        <!-- 关闭按钮 -->
        <div id="ptc" style="display:none;text-align:right;height:15px;position:absolute;top:10px;right:12px;cursor: pointer;">
            <img style="vertical-align:top;" src="" />
        </div> 
    </div>
    <!-- 开启按钮 -->
    <div id="pto" style="height:30px;float:right;text-align: right;overflow:hidden;position:fixed;bottom:0;right:0;color:#000;line-height:30px;cursor:pointer;">
        <div style="background:#232323;color:#FFF;padding:0 6px;float:right;line-height:30px;font-size:14px"></div>
    <img style="width: 30px" title="ShowPageTrace" src="" />
    </div>
    <script type="text/javascript">
    (function(){
        var tab_tit  = document.getElementById('pttt').getElementsByTagName('span');
        var tab_cont = document.getElementById('pttc').getElementsByTagName('div');
        var open     = document.getElementById('pto');
        var close    = document.getElementById('ptc');
        var trace    = document.getElementById('ptt');
        var cookie   = document.cookie.match(/_spt=(\d\|\d)/);
        var history  = (cookie && typeof cookie[1] != 'undefined' && cookie[1].split('|')) || [0,0];
        open.onclick = function(){
            trace.style.display = '';
            close.style.display = '';
            history[0] = 1;
            document.cookie = '_spt='+history.join('|');
        };
        close.onclick = function(){
            trace.style.display = 'none';
            open.style.display = 'block';
            history[0] = 0;
            document.cookie = '_spt='+history.join('|');
        };
        for(var i = 0; i < tab_tit.length; i++){
            tab_tit[i].onclick = (function(i){
                return function(){
                    for(var j = 0; j < tab_cont.length; j++){
                        tab_cont[j].style.display = 'none';
                        tab_tit[j].style.color = '#999';
                    }
                    tab_cont[i].style.display = 'block';
                    tab_tit[i].style.color = '#000';
                    history[1] = i;
                    document.cookie = '_spt='+history.join('|')
                }
            })(i);
        }
        parseInt(history[0]) && open.click();
        (tab_tit[history[1]] || tab_tit[0]).click();
    })();
    </script>
endline;

        }
    }

    if (!SR_IS_AJAX) {
        $headers = Response::getInstance()->getHeaders();
        foreach ($headers as $key => $val) {
            if ('content-type' === strtolower($key)) {
                if (strpos($val, 'html')) {
                    echo new TracePage();
                }
            }
        }
    }
}